#include <stdio.h>
#include <stdlib.h>
#include <curses.h>

#include "sanded.h"
#include "guilib.h"


s_line *first_line = NULL, *last_line = NULL;
s_line *scr_top = NULL;
s_line *curr_line = NULL;
s_text *curr_text=  NULL,*strt_select =NULL,*end_select = NULL;

int scr_x=1,scr_y=1;
int line_num=1,line_cnt=0,cnt_line = 0;
int maxx,maxy;

WINDOW *text_win;
WINDOW *menu_win = NULL,*text_win = NULL,*status_win = NULL;
WINDOW *sub_menu_win = NULL;

char file_name[] ="Untitled";
char file[20] = ".";



/* Static declaration of file menu and its suboptions*/
struct sub_opt	fl_opt[]	=	{
						{" New",fl_new},
						{" Open   F3",fl_open},
						{" Save   F2",fl_save},
						{" Save As",fl_saveas},
						{" Exit   F7",fl_exit}
					};

#define FL_OPT_CNT (sizeof(fl_opt)/sizeof(struct sub_opt))

/* Static declaration of Edit menu and its suboptions*/
struct sub_opt edit_opt[]	=	{
						{" Copy",edit_copy},
						{" Paste",edit_paste},
						{" Cut",edit_cut}
					};

#define EDIT_OPT_CNT (sizeof(edit_opt)/sizeof(struct sub_opt))

struct sub_opt opt_opt[]	=	{
						{"bash Shell",shell},
						{"Colors",color},
						{"Page Setup",setup}
					};
#define OPTIONS_OPT_CNT (sizeof(opt_opt)/sizeof(struct sub_opt))
struct sub_opt help_opt[]	=	{	{"Help Topics F1",help_topic},
						{"About Editor",about_ed}
					};

#define HELP_OPT_CNT (sizeof(help_opt)/sizeof(struct sub_opt))

struct menu main_menu[] = {
				{"File",1,0,FL_OPT_CNT,fl_opt,NULL},
				{"Edit",20,0,EDIT_OPT_CNT,edit_opt,NULL},
				{"Options",40,0,OPTIONS_OPT_CNT,opt_opt,NULL},
				{"Help",60,0,HELP_OPT_CNT,help_opt,NULL}
			};


#define MAIN_MENU_CNT (sizeof(main_menu)/sizeof(struct menu))

void remove_datastructure()
{
	s_line *line,*pre;
	s_text *text,*prev;

	line = first_line;
	while(line)
	{
		text = line->first_text;
		while(text)
		{
			prev = text;
			text = text->right;
			free(prev);
		}
		pre = line;
		line = line->next_line;
		free(pre);
	}
	first_line = NULL;
	last_line = NULL;
	curr_line = NULL;
	curr_text = NULL;
	scr_top = NULL;
	line_cnt = 0;
	line_num = 1;
	scr_x = scr_y = 1;
}

void cursor_left(s_line *curr_line, s_text **curr_text,int *scr_x)
{

	if((*curr_text) == curr_line->first_text)
	{
			printf("\a");
			return;
	}
	if ((*curr_text) != NULL)
			(*curr_text) = (*curr_text)->left;		
	else
		(*curr_text) = curr_line->last_text;
	
	(*scr_x)--;
	return;
}		

void cursor_right(s_line  *curr_line,s_text **curr_text,int *scr_x)
{
	if((*curr_text) == NULL)
	{
		printf("\a");
		return;
	}
	(*curr_text) = (*curr_text)->right;
	(*scr_x)++;
	return;
}

void cursor_up(s_line **curr_line,s_text **curr_text,int *scr_y,int *scr_x)
{
	int cnt=0;
	if((*curr_line)->prev_line == NULL)
	{
			printf("\a");
			return;
	}

	(*curr_line) = (*curr_line)->prev_line;
	
	cnt = (*scr_x) - 1;
	(*curr_text) = (*curr_line)->first_text;
	(*scr_x) = 1;
	if((*curr_text) != NULL)
	{
		while(cnt != 0)
		{
			(*curr_text) = (*curr_text)->right;
			(*scr_x)++;
			if ((*curr_text) == NULL)
				 break;
			cnt--;
		}
	}
	if ((*scr_y) == 1)
	{
		scr_top = (*curr_line);
		refresh_from_line(scr_top,1,(MAXROWS - 2));
	}
	else
		(*scr_y)--;
	line_num--;
	return;
}

void cursor_down(s_line **curr_line,s_text **curr_text,int *scr_y,int *scr_x)
{
	int cnt =0;
	if((*curr_line) == last_line)
	{
		printf("\a");
		return;
	}
	(*curr_line) = (*curr_line)->next_line;
	
	cnt = (*scr_x) - 1;
	(*curr_text) = (*curr_line)->first_text;
	(*scr_x) = 1;
	if((*curr_text) != NULL)
		while(cnt != 0)
		{
			(*curr_text) = (*curr_text)->right;
			(*scr_x)++;
			 if((*curr_text) == NULL)
				 break;
			 cnt--;
		}
	if(*scr_y == (MAXROWS - 2))
	{
		scr_top = scr_top->next_line;
		refresh_from_line(scr_top,1,(MAXROWS - 2));
	}
	else
		(*scr_y)++;
	line_num++;
	return;
}

void cursor_home(s_line *curr_line,s_text **curr_text,int *scr_x)
{
	if(curr_line == NULL || curr_line->first_text == NULL)
	{
		printf("\a");
		return;
	}
	(*curr_text) = curr_line->first_text;
	(*scr_x) = 1;
}

void cursor_end(s_line *curr_line,s_text **curr_text,int *scr_x)
{
	if(curr_line == NULL || curr_line->first_text == NULL)
	{
			printf("\a");
			return;
	}
	(*curr_text) = curr_line->last_text->right;
	(*scr_x) = curr_line->txt_cnt + 1;
}


void handle_del(s_line **curr_line,s_text **curr_text)
{
	s_text *tmp;
	s_line *new_curr_line;
	
	if((*curr_text) == NULL)
	{
		if (((*curr_line)->first_text == NULL) && 
			((*curr_line)->last_text == NULL) &&
			((*curr_line)->next_line != NULL))
		{
			new_curr_line = (*curr_line)->next_line;
			
			delete_empty_line(*curr_line);
			(*curr_line) = new_curr_line;
			(*curr_text) = (*curr_line)->first_text;
			refresh_from_line((*curr_line),scr_y,(MAXROWS - 1));
		}
		else
		{
			printf("\a");
			wrefresh(text_win);
			return;
		}
	}
	else
	{
		tmp = (*curr_text)->right;
				
		delete_text((*curr_line),(*curr_text));

		(*curr_text) = tmp;
		
		
		refresh_curr_line(*curr_line);
		wrefresh(text_win);
	}
	return;

}
void handle_bksp(s_line **curr_line,s_text **curr_text)
{
	s_line *new_curr_line;
	
	/*
	 * If backspaced on first column
	 */
	if ((*curr_text) == (*curr_line)->first_text)
	{
		if (scr_top == (*curr_line))
		{
			printf("\a");
			wrefresh(text_win);
			return;
		}
		else
		{
			if(last_line == (*curr_line))
				last_line = (*curr_line)->prev_line;

			new_curr_line = (*curr_line)->prev_line;
			delete_empty_line(*curr_line);
			line_num--;
			(*curr_line) = new_curr_line;
			(*curr_text) = NULL;
			scr_y--;
			scr_x = (*curr_line)->txt_cnt + 1;
			if (scr_x == 0)
				scr_x = 1;
			refresh_from_line((*curr_line)->next_line,(scr_y + 1),(MAXROWS - 2));
		}
	}
	else
	{
		if((*curr_text) == NULL)
			delete_text(*curr_line,(*curr_line)->last_text);
		else 
			delete_text(*curr_line,(*curr_text)->left);
		scr_x--;
		refresh_curr_line(*curr_line);	
		wrefresh(text_win);
	}
	return;
	
}

void split_line(s_line *curr_line,s_line *new_line,s_text *curr_text)
{
	int cnt = 0;
	s_text *text = curr_text;
	while(text)
	{
		cnt++;
		text = text->right;
	}
	new_line->txt_cnt = cnt;
	curr_line->txt_cnt -= cnt;

	new_line->first_text = curr_text;
	new_line->last_text = curr_line->last_text;

	curr_line->last_text = curr_text->left;
	curr_line->last_text->right = NULL;
	curr_text->left =NULL;
		
}

void handle_enter(s_line **curr_line,s_text **curr_text)
{

	s_line	*new;
	s_line	*refresh_line_start;
	int	refresh_row_start;


	/*
	 * At the first column of the line
	 */
	
	if ((*curr_text) == (*curr_line)->first_text)
	{
		new = create_line((*curr_line)->prev_line);
		
		if (scr_top == (*curr_line))
		{
			scr_top = new;
		}
		if(scr_y == (MAXROWS-2))
		{
			scr_top = scr_top->next_line;
			refresh_line_start = scr_top;
			refresh_row_start = 1;
		}
		else
		{
			refresh_line_start = new;
			refresh_row_start = scr_y;
			scr_y++;
		}

		
	}
	/*
	 * At the last column of the line
	 */

	else if((*curr_text) == NULL)
	{
		new = create_line(*curr_line);
		(*curr_line) = new;
		(*curr_text) = NULL;
		scr_x = 1;

		if(scr_y == (MAXROWS-2))
		{
			scr_top = scr_top->next_line;
			refresh_line_start = scr_top;
			refresh_row_start = 1;
		}
		else
		{
			scr_y++;
			refresh_line_start = new;
			refresh_row_start  = scr_y;
		}
		
	}
	
	/*
	 * In the middle of the line
	 */

	else
	{
		new = create_line(*curr_line);
		(*curr_line) = new;
		split_line(*curr_line,new,*curr_text);
		(*curr_text) = new->first_text;
		scr_x = 1;


		if(scr_y == (MAXROWS - 2))
		{
			scr_top = scr_top->next_line;
			refresh_line_start = scr_top;
			refresh_row_start = 1;
		}
		else
		{
			refresh_line_start = new->prev_line;
			refresh_row_start  = scr_y;
			scr_y++;
		}
	}
	line_num++;
	refresh_from_line(refresh_line_start,refresh_row_start, (MAXROWS-1));

}

void handle_page_up(s_line **curr_line, s_line **scr_top)
{

	int cnt = 1;
	if((*curr_line == NULL) || ((*curr_line)->prev_line == NULL) ||
	 			 (line_cnt <= MAXROWS - 1))
	{
		printf("\a");
		return;
	}
		
	while(((*scr_top)->prev_line) && (cnt <= MAXROWS - 1))
	{
		*scr_top = (*scr_top)->prev_line;
		*curr_line = (*curr_line)->prev_line;
		cnt++;
	}
	refresh_from_line(*scr_top,1,(MAXROWS - 2));
	wrefresh(text_win);
	return;
}


void handle_page_down(s_line **curr_line, s_line **scr_top)
{

	int cnt = 1;
	if((*curr_line == NULL) || ((*curr_line)->next_line == NULL) ||
	 			 (line_cnt <= MAXROWS - 1))
	{
		printf("\a");
		return;
	}

	while(((*curr_line)->next_line) && (cnt <= MAXROWS - 1))
	{
		*scr_top = (*scr_top)->next_line;
		*curr_line = (*curr_line)->next_line;
		cnt++;
	}

	refresh_from_line(*scr_top,1,(MAXROWS - 2));
	wrefresh(text_win);
	return;
}

int save_file(s_line *first_line,char* f_name)
{
	FILE *fp;
	s_line *line;
	s_text *text;

	if (first_line == NULL)
		return -1;
	if (f_name == NULL)
		return -1;
	if ((fp = fopen(f_name,"w")) == NULL)
	{
		printf("Error Opening file %s\n",f_name);
		return -1;
	}
	line =  first_line;
	while (line)
	{
		text = line->first_text;
		while (text)
		{
			fprintf(fp,"%c",text->c);
			text = text->right;
		}
		if(line->next_line != NULL)
			fprintf(fp,"%c",ENTER);
		line = line->next_line;
	}
	fclose(fp);
	return 0;
}

int handle_alt_key()
{
		int key = wgetch(text_win);
		switch(key)
		{

		case F:	
			handle_menu_group(&main_menu[0]);
			wattroff(main_menu[0].win_ptr,A_STANDOUT);
			mvwprintw(main_menu[0].win_ptr,0
					,1,"%s",main_menu[0].menu_name);
			wrefresh(main_menu[0].win_ptr);
			wmove(text_win,1,1);
			break;

		case E:
			handle_menu_group(&main_menu[1]);
			wattroff(main_menu[1].win_ptr,A_STANDOUT);
			mvwprintw(main_menu[1].win_ptr,0,1,"%s",
				main_menu[1].menu_name);
			wrefresh(main_menu[1].win_ptr);
			wmove(text_win,1,1);
			break;

		case H:
			handle_menu_group(&main_menu[3]);
			wattroff(main_menu[3].win_ptr,A_STANDOUT);
			mvwprintw(main_menu[3].win_ptr,0,1,"%s"
				,main_menu[3].menu_name);
			wrefresh(main_menu[3].win_ptr);
			wmove(text_win,1,1);
			break;

		case O:
			handle_menu_group(&main_menu[2]);
			wattroff(main_menu[2].win_ptr,A_STANDOUT);
			mvwprintw(main_menu[2].win_ptr,0,1,"%s"
				,main_menu[2].menu_name);
			wrefresh(main_menu[2].win_ptr);
			wmove(text_win,1,1);
			break;
			
			}
	return key;
}


void find_key()
{
	int key;

	wmove(text_win,1,1);
	key = wgetch(text_win);


	while(key != KEY_F(7))
	{
		if (curr_line == NULL)
		{
			curr_line = create_line(curr_line);
			curr_text = NULL;
			scr_top = curr_line;
		}
		switch(key)
		{
			case KEY_F(2):
					main_menu[0].s_opt[2].sub_opt_fn();
					save_file(first_line,file_name);
					break;

			case KEY_F(3):
					main_menu[0].s_opt[1].sub_opt_fn();
					break;
			case KEY_F(1):
					main_menu[333].s_opt[0].sub_opt_fn();
					break;

			case ENTER:
					handle_enter(&curr_line,&curr_text);
					break;
			case BKSP:
					handle_bksp(&curr_line,&curr_text);
					break;
			case DEL:
					handle_del(&curr_line,&curr_text);
					break;
			case INS:
					break;
			case HOME:
					cursor_home(curr_line,
							&curr_text,&scr_x);
					break;
			case END:
					cursor_end(curr_line,
							&curr_text,&scr_x);
					break;
			case PG_UP:
					handle_page_up(&curr_line,&scr_top);
					break;
			case PG_DOWN:
					handle_page_down(&curr_line,&scr_top);
					break;
			case TAB:
					break;
			case KEY_LEFT:
					cursor_left(curr_line,
							&curr_text,&scr_x);
					break;
			case KEY_RIGHT:
					cursor_right(curr_line,
							&curr_text,&scr_x);
					break;
			case KEY_UP:
					cursor_up(&curr_line,
							&curr_text,&scr_y,
							&scr_x);
					cnt_line--;
					break;

			case KEY_DOWN:
					cursor_down(&curr_line,
							&curr_text,&scr_y,
							&scr_x);
					cnt_line++;
					break;
			case ALT :
					key = handle_alt_key();		
					break;
					
			case CTRL_F:
					strt_select = curr_text;
					cnt_line = 0;
					break;

			case CTRL_L:
					//wprintw(text_win,"SHIFT_RIGHT selected\n");
					end_select = curr_text;
					break;
			default:
					insert_text(curr_line,&curr_text,key);
					refresh_curr_line(curr_line);

		}
		mvwprintw(status_win,1,1,
				"[%s]\t\tLine:%d\t\tCol:%d\t\t"
				,file_name,line_num,scr_x);
		wmove(text_win,scr_y,scr_x);
		box(text_win,0,0);
		wrefresh(status_win);
		wrefresh(text_win);
		key = wgetch(text_win);
	}
	return;
}

int main()
{

	clear();
	initscr();
	cbreak();
	noecho();

	getmaxyx(stdscr,maxy,maxx);

	if(!has_colors())
		wprintw(text_win,"No colour support\n");
	else
		start_color();

	init_pair(1,COLOR_WHITE,COLOR_BLUE);
	init_pair(2,COLOR_BLACK,COLOR_WHITE);
	init_pair(3,COLOR_CYAN,COLOR_BLACK);
	init_pair(4,COLOR_BLACK,COLOR_YELLOW);
	init_pair(5,COLOR_BLUE,COLOR_WHITE);
	init_pair(6,COLOR_WHITE,COLOR_BLACK);
	init_pair(7,COLOR_BLACK,COLOR_CYAN);
	init_pair(8,COLOR_YELLOW,COLOR_WHITE);
	init_pair(9,COLOR_WHITE,COLOR_YELLOW);
		
	
	text_win = newwin(maxy - 2,0,1,0);
	wbkgd(text_win,COLOR_PAIR(1));
	wborder(text_win,0,0,0,0,0,0,0,0);
	
	menu_win = newwin(2,0,0,0);
	wbkgd(menu_win,COLOR_PAIR(2));
//	box(menu_win,0,0);

//	wrefresh(menu_win);

	status_win = newwin(2,maxx,maxy-2,0);
	wbkgd(status_win,COLOR_PAIR(2));
//	box(status_win,0,0);
	wrefresh(status_win);


	getmaxyx(text_win,maxy,maxx);

	keypad(menu_win,TRUE);
	keypad(text_win,TRUE);

	draw_menu(main_menu,MAIN_MENU_CNT);
	mvwprintw(status_win,1,1,"[%s]\t\tLine:%d\t\tCol:%d\t\t"
			,file_name,line_num,scr_x);
	wrefresh(status_win);
	wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>

#include "sanded.h"
#include "guilib.h"


s_line *first_line = NULL, *last_line = NULL;
s_line *scr_top = NULL;
s_line *curr_line = NULL;
s_text *curr_text=  NULL,*strt_select =NULL,*end_select = NULL;

int scr_x=1,scr_y=1;
int line_num=1,line_cnt=0,cnt_line = 0;
int maxx,maxy;

WINDOW *text_win;
WINDOW *menu_win = NULL,*text_win = NULL,*status_win = NULL;
WINDOW *sub_menu_win = NULL;

char file_name[] ="Untitled";
char file[20] = ".";



/* Static declaration of file menu and its suboptions*/
struct sub_opt	fl_opt[]	=	{
						{" New",fl_new},
						{" Open   F3",fl_open},
						{" Save   F2",fl_save},
						{" Save As",fl_saveas},
						{" Exit   F7",fl_exit}
					};

#define FL_OPT_CNT (sizeof(fl_opt)/sizeof(struct sub_opt))

/* Static declaration of Edit menu and its suboptions*/
struct sub_opt edit_opt[]	=	{
						{" Copy",edit_copy},
						{" Paste",edit_paste},
						{" Cut",edit_cut}
					};

#define EDIT_OPT_CNT (sizeof(edit_opt)/sizeof(struct sub_opt))

struct sub_opt opt_opt[]	=	{
						{"bash Shell",shell},
						{"Colors",color},
						{"Page Setup",setup}
					};
#define OPTIONS_OPT_CNT (sizeof(opt_opt)/sizeof(struct sub_opt))
struct sub_opt help_opt[]	=	{	{"Help Topics F1",help_topic},
						{"About Editor",about_ed}
					};

#define HELP_OPT_CNT (sizeof(help_opt)/sizeof(struct sub_opt))

struct menu main_menu[] = {
				{"File",1,0,FL_OPT_CNT,fl_opt,NULL},
				{"Edit",20,0,EDIT_OPT_CNT,edit_opt,NULL},
				{"Options",40,0,OPTIONS_OPT_CNT,opt_opt,NULL},
				{"Help",60,0,HELP_OPT_CNT,help_opt,NULL}
			};


#define MAIN_MENU_CNT (sizeof(main_menu)/sizeof(struct menu))

void remove_datastructure()
{
	s_line *line,*pre;
	s_text *text,*prev;

	line = first_line;
	while(line)
	{
		text = line->first_text;
		while(text)
		{
			prev = text;
			text = text->right;
			free(prev);
		}
		pre = line;
		line = line->next_line;
		free(pre);
	}
	first_line = NULL;
	last_line = NULL;
	curr_line = NULL;
	curr_text = NULL;
	scr_top = NULL;
	line_cnt = 0;
	line_num = 1;
	scr_x = scr_y = 1;
}

void cursor_left(s_line *curr_line, s_text **curr_text,int *scr_x)
{

	if((*curr_text) == curr_line->first_text)
	{
			printf("\a");
			return;
	}
	if ((*curr_text) != NULL)
			(*curr_text) = (*curr_text)->left;		
	else
		(*curr_text) = curr_line->last_text;
	
	(*scr_x)--;
	return;
}		

void cursor_right(s_line  *curr_line,s_text **curr_text,int *scr_x)
{
	if((*curr_text) == NULL)
	{
		printf("\a");
		return;
	}
	(*curr_text) = (*curr_text)->right;
	(*scr_x)++;
	return;
}

void cursor_up(s_line **curr_line,s_text **curr_text,int *scr_y,int *scr_x)
{
	int cnt=0;
	if((*curr_line)->prev_line == NULL)
	{
			printf("\a");
			return;
	}

	(*curr_line) = (*curr_line)->prev_line;
	
	cnt = (*scr_x) - 1;
	(*curr_text) = (*curr_line)->first_text;
	(*scr_x) = 1;
	if((*curr_text) != NULL)
	{
		while(cnt != 0)
		{
			(*curr_text) = (*curr_text)->right;
			(*scr_x)++;
			if ((*curr_text) == NULL)
				 break;
			cnt--;
		}
	}
	if ((*scr_y) == 1)
	{
		scr_top = (*curr_line);
		refresh_from_line(scr_top,1,(MAXROWS - 2));
	}
	else
		(*scr_y)--;
	line_num--;
	return;
}

void cursor_down(s_line **curr_line,s_text **curr_text,int *scr_y,int *scr_x)
{
	int cnt =0;
	if((*curr_line) == last_line)
	{
		printf("\a");
		return;
	}
	(*curr_line) = (*curr_line)->next_line;
	
	cnt = (*scr_x) - 1;
	(*curr_text) = (*curr_line)->first_text;
	(*scr_x) = 1;
	if((*curr_text) != NULL)
		while(cnt != 0)
		{
			(*curr_text) = (*curr_text)->right;
			(*scr_x)++;
			 if((*curr_text) == NULL)
				 break;
			 cnt--;
		}
	if(*scr_y == (MAXROWS - 2))
	{
		scr_top = scr_top->next_line;
		refresh_from_line(scr_top,1,(MAXROWS - 2));
	}
	else
		(*scr_y)++;
	line_num++;
	return;
}

void cursor_home(s_line *curr_line,s_text **curr_text,int *scr_x)
{
	if(curr_line == NULL || curr_line->first_text == NULL)
	{
		printf("\a");
		return;
	}
	(*curr_text) = curr_line->first_text;
	(*scr_x) = 1;
}

void cursor_end(s_line *curr_line,s_text **curr_text,int *scr_x)
{
	if(curr_line == NULL || curr_line->first_text == NULL)
	{
			printf("\a");
			return;
	}
	(*curr_text) = curr_line->last_text->right;
	(*scr_x) = curr_line->txt_cnt + 1;
}


void handle_del(s_line **curr_line,s_text **curr_text)
{
	s_text *tmp;
	s_line *new_curr_line;
	
	if((*curr_text) == NULL)
	{
		if (((*curr_line)->first_text == NULL) && 
			((*curr_line)->last_text == NULL) &&
			((*curr_line)->next_line != NULL))
		{
			new_curr_line = (*curr_line)->next_line;
			
			delete_empty_line(*curr_line);
			(*curr_line) = new_curr_line;
			(*curr_text) = (*curr_line)->first_text;
			refresh_from_line((*curr_line),scr_y,(MAXROWS - 1));
		}
		else
		{
			printf("\a");
			wrefresh(text_win);
			return;
		}
	}
	else
	{
		tmp = (*curr_text)->right;
				
		delete_text((*curr_line),(*curr_text));

		(*curr_text) = tmp;
		
		
		refresh_curr_line(*curr_line);
		wrefresh(text_win);
	}
	return;

}
void handle_bksp(s_line **curr_line,s_text **curr_text)
{
	s_line *new_curr_line;
	
	/*
	 * If backspaced on first column
	 */
	if ((*curr_text) == (*curr_line)->first_text)
	{
		if (scr_top == (*curr_line))
		{
			printf("\a");
			wrefresh(text_win);
			return;
		}
		else
		{
			if(last_line == (*curr_line))
				last_line = (*curr_line)->prev_line;

			new_curr_line = (*curr_line)->prev_line;
			delete_empty_line(*curr_line);
			line_num--;
			(*curr_line) = new_curr_line;
			(*curr_text) = NULL;
			scr_y--;
			scr_x = (*curr_line)->txt_cnt + 1;
			if (scr_x == 0)
				scr_x = 1;
			refresh_from_line((*curr_line)->next_line,(scr_y + 1),(MAXROWS - 2));
		}
	}
	else
	{
		if((*curr_text) == NULL)
			delete_text(*curr_line,(*curr_line)->last_text);
		else 
			delete_text(*curr_line,(*curr_text)->left);
		scr_x--;
		refresh_curr_line(*curr_line);	
		wrefresh(text_win);
	}
	return;
	
}

void split_line(s_line *curr_line,s_line *new_line,s_text *curr_text)
{
	int cnt = 0;
	s_text *text = curr_text;
	while(text)
	{
		cnt++;
		text = text->right;
	}
	new_line->txt_cnt = cnt;
	curr_line->txt_cnt -= cnt;

	new_line->first_text = curr_text;
	new_line->last_text = curr_line->last_text;

	curr_line->last_text = curr_text->left;
	curr_line->last_text->right = NULL;
	curr_text->left =NULL;
		
}

void handle_enter(s_line **curr_line,s_text **curr_text)
{

	s_line	*new;
	s_line	*refresh_line_start;
	int	refresh_row_start;


	/*
	 * At the first column of the line
	 */
	
	if ((*curr_text) == (*curr_line)->first_text)
	{
		new = create_line((*curr_line)->prev_line);
		
		if (scr_top == (*curr_line))
		{
			scr_top = new;
		}
		if(scr_y == (MAXROWS-2))
		{
			scr_top = scr_top->next_line;
			refresh_line_start = scr_top;
			refresh_row_start = 1;
		}
		else
		{
			refresh_line_start = new;
			refresh_row_start = scr_y;
			scr_y++;
		}

		
	}
	/*
	 * At the last column of the line
	 */

	else if((*curr_text) == NULL)
	{
		new = create_line(*curr_line);
		(*curr_line) = new;
		(*curr_text) = NULL;
		scr_x = 1;

		if(scr_y == (MAXROWS-2))
		{
			scr_top = scr_top->next_line;
			refresh_line_start = scr_top;
			refresh_row_start = 1;
		}
		else
		{
			scr_y++;
			refresh_line_start = new;
			refresh_row_start  = scr_y;
		}
		
	}
	
	/*
	 * In the middle of the line
	 */

	else
	{
		new = create_line(*curr_line);
		(*curr_line) = new;
		split_line(*curr_line,new,*curr_text);
		(*curr_text) = new->first_text;
		scr_x = 1;


		if(scr_y == (MAXROWS - 2))
		{
			scr_top = scr_top->next_line;
			refresh_line_start = scr_top;
			refresh_row_start = 1;
		}
		else
		{
			refresh_line_start = new->prev_line;
			refresh_row_start  = scr_y;
			scr_y++;
		}
	}
	line_num++;
	refresh_from_line(refresh_line_start,refresh_row_start, (MAXROWS-1));

}

void handle_page_up(s_line **curr_line, s_line **scr_top)
{

	int cnt = 1;
	if((*curr_line == NULL) || ((*curr_line)->prev_line == NULL) ||
	 			 (line_cnt <= MAXROWS - 1))
	{
		printf("\a");
		return;
	}
		
	while(((*scr_top)->prev_line) && (cnt <= MAXROWS - 1))
	{
		*scr_top = (*scr_top)->prev_line;
		*curr_line = (*curr_line)->prev_line;
		cnt++;
	}
	refresh_from_line(*scr_top,1,(MAXROWS - 2));
	wrefresh(text_win);
	return;
}


void handle_page_down(s_line **curr_line, s_line **scr_top)
{

	int cnt = 1;
	if((*curr_line == NULL) || ((*curr_line)->next_line == NULL) ||
	 			 (line_cnt <= MAXROWS - 1))
	{
		printf("\a");
		return;
	}

	while(((*curr_line)->next_line) && (cnt <= MAXROWS - 1))
	{
		*scr_top = (*scr_top)->next_line;
		*curr_line = (*curr_line)->next_line;
		cnt++;
	}

	refresh_from_line(*scr_top,1,(MAXROWS - 2));
	wrefresh(text_win);
	return;
}

int save_file(s_line *first_line,char* f_name)
{
	FILE *fp;
	s_line *line;
	s_text *text;

	if (first_line == NULL)
		return -1;
	if (f_name == NULL)
		return -1;
	if ((fp = fopen(f_name,"w")) == NULL)
	{
		printf("Error Opening file %s\n",f_name);
		return -1;
	}
	line =  first_line;
	while (line)
	{
		text = line->first_text;
		while (text)
		{
			fprintf(fp,"%c",text->c);
			text = text->right;
		}
		if(line->next_line != NULL)
			fprintf(fp,"%c",ENTER);
		line = line->next_line;
	}
	fclose(fp);
	return 0;
}

int handle_alt_key()
{
		int key = wgetch(text_win);
		switch(key)
		{

		case F:	
			handle_menu_group(&main_menu[0]);
			wattroff(main_menu[0].win_ptr,A_STANDOUT);
			mvwprintw(main_menu[0].win_ptr,0
					,1,"%s",main_menu[0].menu_name);
			wrefresh(main_menu[0].win_ptr);
			wmove(text_win,1,1);
			break;

		case E:
			handle_menu_group(&main_menu[1]);
			wattroff(main_menu[1].win_ptr,A_STANDOUT);
			mvwprintw(main_menu[1].win_ptr,0,1,"%s",
				main_menu[1].menu_name);
			wrefresh(main_menu[1].win_ptr);
			wmove(text_win,1,1);
			break;

		case H:
			handle_menu_group(&main_menu[3]);
			wattroff(main_menu[3].win_ptr,A_STANDOUT);
			mvwprintw(main_menu[3].win_ptr,0,1,"%s"
				,main_menu[3].menu_name);
			wrefresh(main_menu[3].win_ptr);
			wmove(text_win,1,1);
			break;

		case O:
			handle_menu_group(&main_menu[2]);
			wattroff(main_menu[2].win_ptr,A_STANDOUT);
			mvwprintw(main_menu[2].win_ptr,0,1,"%s"
				,main_menu[2].menu_name);
			wrefresh(main_menu[2].win_ptr);
			wmove(text_win,1,1);
			break;
			
			}
	return key;
}


void find_key()
{
	int key;

	wmove(text_win,1,1);
	key = wgetch(text_win);


	while(key != KEY_F(7))
	{
		if (curr_line == NULL)
		{
			curr_line = create_line(curr_line);
			curr_text = NULL;
			scr_top = curr_line;
		}
		switch(key)
		{
			case KEY_F(2):
					main_menu[0].s_opt[2].sub_opt_fn();
					save_file(first_line,file_name);
					break;

			case KEY_F(3):
					main_menu[0].s_opt[1].sub_opt_fn();
					break;
			case KEY_F(1):
					main_menu[333].s_opt[0].sub_opt_fn();
					break;

			case ENTER:
					handle_enter(&curr_line,&curr_text);
					break;
			case BKSP:
					handle_bksp(&curr_line,&curr_text);
					break;
			case DEL:
					handle_del(&curr_line,&curr_text);
					break;
			case INS:
					break;
			case HOME:
					cursor_home(curr_line,
							&curr_text,&scr_x);
					break;
			case END:
					cursor_end(curr_line,
							&curr_text,&scr_x);
					break;
			case PG_UP:
					handle_page_up(&curr_line,&scr_top);
					break;
			case PG_DOWN:
					handle_page_down(&curr_line,&scr_top);
					break;
			case TAB:
					break;
			case KEY_LEFT:
					cursor_left(curr_line,
							&curr_text,&scr_x);
					break;
			case KEY_RIGHT:
					cursor_right(curr_line,
							&curr_text,&scr_x);
					break;
			case KEY_UP:
					cursor_up(&curr_line,
							&curr_text,&scr_y,
							&scr_x);
					cnt_line--;
					break;

			case KEY_DOWN:
					cursor_down(&curr_line,
							&curr_text,&scr_y,
							&scr_x);
					cnt_line++;
					break;
			case ALT :
					key = handle_alt_key();		
					break;
					
			case CTRL_F:
					strt_select = curr_text;
					cnt_line = 0;
					break;

			case CTRL_L:
					//wprintw(text_win,"SHIFT_RIGHT selected\n");
					end_select = curr_text;
					break;
			default:
					insert_text(curr_line,&curr_text,key);
					refresh_curr_line(curr_line);

		}
		mvwprintw(status_win,1,1,
				"[%s]\t\tLine:%d\t\tCol:%d\t\t"
				,file_name,line_num,scr_x);
		wmove(text_win,scr_y,scr_x);
		box(text_win,0,0);
		wrefresh(status_win);
		wrefresh(text_win);
		key = wgetch(text_win);
	}
	return;
}

int main()
{

	clear();
	initscr();
	cbreak();
	noecho();

	getmaxyx(stdscr,maxy,maxx);

	if(!has_colors())
		wprintw(text_win,"No colour support\n");
	else
		start_color();

	init_pair(1,COLOR_WHITE,COLOR_BLUE);
	init_pair(2,COLOR_BLACK,COLOR_WHITE);
	init_pair(3,COLOR_CYAN,COLOR_BLACK);
	init_pair(4,COLOR_BLACK,COLOR_YELLOW);
	init_pair(5,COLOR_BLUE,COLOR_WHITE);
	init_pair(6,COLOR_WHITE,COLOR_BLACK);
	init_pair(7,COLOR_BLACK,COLOR_CYAN);
	init_pair(8,COLOR_YELLOW,COLOR_WHITE);
	init_pair(9,COLOR_WHITE,COLOR_YELLOW);
		
	
	text_win = newwin(maxy - 2,0,1,0);
	wbkgd(text_win,COLOR_PAIR(1));
	wborder(text_win,0,0,0,0,0,0,0,0);
	
	menu_win = newwin(2,0,0,0);
	wbkgd(menu_win,COLOR_PAIR(2));
//	box(menu_win,0,0);

//	wrefresh(menu_win);

	status_win = newwin(2,maxx,maxy-2,0);
	wbkgd(status_win,COLOR_PAIR(2));
//	box(status_win,0,0);
	wrefresh(status_win);


	getmaxyx(text_win,maxy,maxx);

	keypad(menu_win,TRUE);
	keypad(text_win,TRUE);

	draw_menu(main_menu,MAIN_MENU_CNT);
	mvwprintw(status_win,1,1,"[%s]\t\tLine:%d\t\tCol:%d\t\t"
			,file_name,line_num,scr_x);
	wrefresh(status_win);
	wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}

wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}wrefresh(menu_win);
	wrefresh(text_win);
	draw_entrance_win();



	find_key();


	wrefresh(text_win);
	wrefresh(menu_win);
	wrefresh(status_win);
	endwin();
	system("clear");
	return 0;
}